/**
 * Created by IntelliJ IDEA.
 *
 * User: r.galimov
 * Date: 18.08.13 15:33
 */
package ru.mail.games.BB.modules.gui.slicesPanels {
import ru.mail.games.BB.modules.dynamicallyLoaded.DynamicallyLoaded;
import ru.mail.games.BB.modules.dynamicallyLoaded.IDynamicallyLoaded;
import ru.mail.games.BB.modules.gui.CSprite;
import ru.mail.games.BB.modules.gui.GuiFactory;
import ru.mail.games.BB.modules.gui.images.SimpleImage;
import ru.mail.games.BB.utils.scaling.Size;

public class SymmetricSprite extends CSprite implements IDynamicallyLoaded {

    private var imageResourceId:String;
    private var atlasPath: String;
    private var symmetryType:SymmetryType;

    private var topLeftPart:SimpleImage;
    private var topRightPart:SimpleImage;
    private var bottomLeftPart:SimpleImage;
    private var bottomRightPart:SimpleImage;

    private var innerWidth:Number;
    private var innerHeight:Number;

    private var dynamicallyLoaded : DynamicallyLoaded = new DynamicallyLoaded();


    public function SymmetricSprite(symmetryType:SymmetryType, imageResourceId:String, atlasPath: String) {
        super();
        this.imageResourceId = imageResourceId;
        this.atlasPath = atlasPath;
        this.symmetryType = symmetryType;
        init();
    }

    private function init():void {
        startLoading();
        createTopLeftPart();
        if(symmetryType.hasHReflect()){
            createTopRightPart();
        }
        if(symmetryType.hasVReflect()){
            createBottomLeftPart();
        }
        if(symmetryType.hasDualReflect()){
            createBottomRightPart();
        }
    }

    public function changeImage(imageResourceId:String):void {
        startLoading();

        this.imageResourceId = imageResourceId;

        topLeftPart.changeImage(imageResourceId);

        if(topRightPart){
            topRightPart.changeImage(imageResourceId);
        }
        if(bottomLeftPart){
            bottomLeftPart.changeImage(imageResourceId);
        }
        if(bottomRightPart){
            bottomRightPart.changeImage(imageResourceId);
        }
    }


    private function createTopLeftPart():void {
        topLeftPart = GuiFactory.createSimpleImage(imageResourceId, atlasPath);
        topLeftPart.setLoadCallback(onResourceLoaded);
        addChild(topLeftPart);
    }

    private function createTopRightPart():void {
        topRightPart = GuiFactory.createSimpleImage(imageResourceId, atlasPath);
        topRightPart.scaleX = -1;
        topRightPart.setLoadCallback(onResourceLoaded);
        addChild(topRightPart);
    }

    private function createBottomLeftPart():void {
        bottomLeftPart = GuiFactory.createSimpleImage(imageResourceId, atlasPath);
        bottomLeftPart.scaleY = -1;
        bottomLeftPart.setLoadCallback(onResourceLoaded);
        addChild(bottomLeftPart);
    }

    private function createBottomRightPart():void {
        bottomRightPart = GuiFactory.createSimpleImage(imageResourceId, atlasPath);
        bottomRightPart.scaleX = -1;
        bottomRightPart.scaleY = -1;
        bottomRightPart.setLoadCallback(onResourceLoaded);
        addChild(bottomRightPart);
    }

    private function onResourceLoaded():void {
        if ( !isContentLoaded() ) return;

        if (!innerWidth) {
            innerWidth = topLeftPart.width + (topRightPart ? topRightPart.width : 0);
        }
        if (!innerHeight) {
            innerHeight = topLeftPart.height + (bottomLeftPart ? bottomLeftPart.height : 0);
        }

        readjustSize();

        finishLoading();
    }

    override public function setSize(size:Size):void {
        innerWidth = size.width;
        innerHeight = size.height;
        if (isLoaded()) {
            if (innerWidth == 0 || innerHeight == 0) {
                visible = false;
                return;
            }
            visible = true;
            readjustSize();
        }
    }


    private function readjustSize():void {

        var onePartWidth:Number = symmetryType.hasHReflect() ? innerWidth/2 : innerWidth;
        var onePartHeight:Number = symmetryType.hasVReflect() ? innerHeight/2 : innerHeight;

        topLeftPart.setSize(onePartWidth, onePartHeight);
        if(topRightPart){
            topRightPart.setScale(-topLeftPart.scaleX, topLeftPart.scaleY);
        }
        if(bottomLeftPart){
            bottomLeftPart.setScale(topLeftPart.scaleX, -topLeftPart.scaleY);
        }
        if(bottomRightPart){
            bottomRightPart.setScale(-topLeftPart.scaleX, -topLeftPart.scaleY);
        }

        arrange();
    }

    private function arrange():void {
        topLeftPart.setPosition(0, 0);
        if(topRightPart){
            topRightPart.setPosition(topLeftPart.x + topLeftPart.width*2, 0);
        }
        if(bottomLeftPart){
            bottomLeftPart.setPosition(0, topLeftPart.y + topLeftPart.height*2);
        }
        if(bottomRightPart){
            bottomRightPart.setPosition(topLeftPart.x + topLeftPart.width*2, topLeftPart.y + topLeftPart.height*2);
        }
    }

    override public function set width(width:Number):void {
        setSize(new Size(width, innerHeight));
    }


    override public function set height(height:Number):void {
        setSize(new Size(innerWidth, height));
    }


    override public function get width():Number {
        return innerWidth * scaleX;
    }


    override public function get height():Number {
        return innerHeight * scaleY;
    }

    public function isContentLoaded():Boolean {
        return topLeftPart && topLeftPart.isLoaded() &&
                (!symmetryType.hasHReflect() || topRightPart && topRightPart.isLoaded()) &&
                (!symmetryType.hasVReflect() || bottomLeftPart && bottomLeftPart.isLoaded()) &&
                (!symmetryType.hasDualReflect() || bottomRightPart && bottomRightPart.isLoaded());
    }


    public function setLoadCallback(callback:Function):void {
        dynamicallyLoaded.setLoadCallback( callback );
    }

    public function isLoaded():Boolean {
        return dynamicallyLoaded.isLoaded();
    }

    private function startLoading():void {
        dynamicallyLoaded.startLoading();
    }

    private function finishLoading():void {
        dynamicallyLoaded.finishLoading();
    }


}
}
